-- UICommunicating
-- Created by huanghr
-- 通信中界面

UICommunicating = class("UICommunicating", function()
    return cc.Layer:create();
end);

function UICommunicating.create(title, showTips, pauseEffect, timeout, titleType, startDungeon)
    return UICommunicating.new(title, showTips, pauseEffect, timeout, titleType, startDungeon);
end

-- 进度条光效偏移
local offsetX = 0;
local offsetY = 25;

-- 草地偏移
local grassOffset = ({18, 40, 60, 74, 82});

-- 长花的概率
local flowerProb = 50;

-- 构造函数
function UICommunicating:ctor(title, showTips, pauseEffect, timeout, titleType, startDungeon)
    -- 加载合图
    cc.SpriteFrameCache:getInstance():addSpriteFrames("images/ui/login_effect.plist");

    -- 初始化
    self:setName("UICommunicating");
    local node = cc.CSLoader:createNode("layout/common/CommunicatingForm.csb");
    self:addChild(node);
    self.node = node;
    self.bt = findChildByName(self.node, "bt");

    self.showTips = showTips;

    self.specialShow = false;

    if CommunicatingTipsM.isShowCurTypeTip(titleType, startDungeon) then
        self.specialShow = true;
        CommunicatingTipsM.resetCurTipList(titleType);
    end

    -- 如果在迷宫中，需要将层级调高
    if DungeonM.isInDungeon() then
        self:setLocalZOrder(UIMgr.BONUS_NOTIFY_ZORDER + 2);
    else
        self:setLocalZOrder(UIMgr.BONUS_NOTIFY_ZORDER + 1);
    end

    self.title = title or getLocStr("communicate_with_server");

    self.pauseEffect = pauseEffect;

    self.loadingBar1BG = findChildByName(self.bt, "progress_bg");

    -- 进度条动画
    local pNode = cc.Node:create();
    local barEffect = ccui.ImageView:create();
    barEffect:loadTexture("images/ui/login/effect/progress_gb.png");
    barEffect:setAnchorPoint(cc.p(0.5, 0));
    self.barEffect = barEffect;
    self.initPosY = self.barEffect:getPositionY();
    pNode:addChild(barEffect);
    self.pNode = pNode;
    self.pNode:setPosition(0, self.loadingBar1BG:getPositionY() + 25);
    self.bt:addChild(self.pNode);
    self.pNode:setVisible(false);

    -- 适配
    self:resize();

    -- 重绘
    self:redraw();

    -- 注册事件回调
    self:registerEventCallback();

    -- 如果指定了超时时间，定时关闭
    if type(timeout) == "number" then
        local function closeMe()
            trace("UICommunicating", "超时自动关闭界面");
            closeFormByName("UICommunicating");
        end
        performWithDelay(self, closeMe, timeout);
    end
end

-- 注册事件回调
function UICommunicating:registerEventCallback()
    EventMgr.removeAll("UICommunicating");

    -- 关注关闭通讯中界面的事件
    EventMgr.register("UICommunicating", event.CLOSE_COMMUNICATE_FORM, function()
        -- 如果有展示小贴士的话，需要先播放完进度条动画
        if self.showTips then
            self:finishProgressAnimation();
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UICommunicating 界面析构清理");
            EventMgr.removeAll("UICommunicating");
        end
    end);
end

-- 适配
function UICommunicating:resize()
    local node = self.node;
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    local blackMask = findChildByName(node, "black_mask");
    blackMask:setPosition(w / 2, h / 2);
    local scaleCo = math.max(w / 768, h / 1136);
    blackMask:setScale(scaleCo);
    self.blackMask = blackMask;

    -- 蒙版居中显示并充满整个屏幕
    local blackMask2 = findChildByName(node, "black_mask2");
    AlignM.fitToScreen(node, "black_mask2");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT底部居中并缩放至合适大小
    AlignM.alignToBottomCenter(node, "bt");
end

-- 重绘
function UICommunicating:redraw()

    if self.specialShow then
        self:updateTitle();
        self:resetPos();
    end

    -- 显示小贴士
    local tip = LoadingTipsM.getTip();

    local tipLabel = findChildByName(self.node, "bt/tips/text");
    if self.showTips then
        tipLabel:setVisible(true);
        TextStyleM.setTextStyle(tipLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_GRAY);
        applyString(tipLabel, tip);

        self.blackMask:setVisible(true);

        -- 随机加载背景图片
        local bgList = {"bg3", "bg4"};

        -- 随机加载一张背景图
        local index = math.random(1, #bgList);
        self.blackMask:loadTexture(getLoginIcon(bgList[index]));
    else
        tipLabel:setVisible(false);
        self.blackMask:setVisible(false);
    end

    local letterNode;
    if self.specialShow then
        letterNode = findChildByName(self.node, "CT/title_label");
    else
        letterNode = findChildByName(self.node, "CT/communicating_label");
    end

    if not self.showTips then
        self:setTipStyle(letterNode);
        self:showCommunicateText(letterNode);
        self:playWaitingEffect();
    else
        letterNode:setVisible(false);

        local communicatingLabel = findChildByName(self.node, "bt/tips/communicating_label2");
        communicatingLabel:setVisible(true);
        TextStyleM.setTextStyle(communicatingLabel, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_ORANGE, true, nil, nil, nil, nil, nil, true);
        communicatingLabel:setString(self.title);

        -- 如果有多行，做一个向上偏移
        local size = communicatingLabel:getContentSize();
        local lineH = communicatingLabel:getVirtualRenderer():getLineHeight();
        local lineAmount = size.height/lineH;
        if  lineAmount > 1 then
            if not self.initLabel2PosY then
                self.initLabel2PosY = communicatingLabel:getPositionY();
            end

            local posY = self.initLabel2PosY + TextStyleM.TEXT_SIZE_MIDDLE * (lineAmount - 1);
            communicatingLabel:setPositionY(posY);
        end

        -- 进度条动画
        self.loadingBar1BG:setVisible(true);
        self:progressBarEffect(0.02);
        self:playProgressAnimation();

        local blackMask2 = findChildByName(self.node, "black_mask2");
        blackMask2:setVisible(true);
    end
end

-- 通信文字
function UICommunicating:showCommunicateText(letterNode)
    -- 处理文字跳动相关函数
    local count = 4;

    local function dealAction(count, letterNode, mainNode)
        local jumpFlag = 1;

        local function jump()
            local a = letterNode;
            local str = self.title;
            if jumpFlag == count then
                jumpFlag = 1;
            end
            for i = 1, jumpFlag do
               str = str .. "."
            end
            letterNode:setString(str);
            jumpFlag = jumpFlag + 1;
            performWithDelay(mainNode, jump, 0.2);
        end

        jump();
    end

    dealAction(count, letterNode, self);
end

-- 播放等待特效
function UICommunicating:playWaitingEffect()
    local modelNode = findChildByName(self.node, "CT/effect_node");
    local icon = findChildByName(self.node, "CT/effect_icon");
    local function playWaiting()
        modelNode:removeAllChildren();
        playEffect(modelNode, 2054, 0, -10);
        performWithDelay(modelNode, playWaiting, 0.5);
    end
    playWaiting();
end

function UICommunicating:playPauseEffect()
    local effectNode = findChildByName(self.node, "CT/effect_node");
    local effectNode2 = findChildByName(self.node, "CT/effect_node2");

    playEffect(effectNode, 1291, 0, 0);
    playEffect(effectNode2, 1292, 0, 0);
end

-- 重置通信中的位置
function UICommunicating:resetPos()
    local modelNode = findChildByName(self.node, "CT/effect_node");
    local communicatingLabel = findChildByName(self.node, "CT/communicating_label");
    communicatingLabel:setVisible(false);
    local titleLabel = findChildByName(self.node, "CT/title_label");

    titleLabel:setVisible(true);
    modelNode:setPosition(0, 100);
end

-- 重置当前标题
function UICommunicating:updateTitle()
    local letterNode = findChildByName(self.node, "CT/title_label");
    self:setTipStyle(letterNode);
    letterNode:setVisible(false);

    local titleLabel = findChildByName(self.node, "CT/title_label");
    local function getNewTip()
        self.title = CommunicatingTipsM.getTip();

        letterNode:setString(self.title);
        local textWidth = letterNode:getContentSize().width;

        titleLabel:setPositionX(- textWidth/2 - 10);

        performWithDelay(self, getNewTip, 1);
    end

    getNewTip();
end

-- 设置层级
function UICommunicating:setTipStyle(letterNode)
    TextStyleM.setTextStyle(letterNode, TextStyleM.TEXT_SIZE_LARGE, TextStyleM.TEXT_COLOR_ORANGE, true, nil, nil, nil, nil, nil, true);
end

-- 进度条冈布奥跳动动画
function UICommunicating:progressBarEffect(during, height)
    height = height or 20

    self.pNode:setVisible(true);
    local node = self.barEffect;

    local scaleX = node:getScaleX();
    local scaleY = node:getScaleY();
    local posY   = self.initPosY;

    -- 向上部分
    local moveUp = cc.EaseIn:create(cc.MoveTo:create(during*3, cc.p(node:getPositionX(), height)), 0.25);

    -- 下降部分
    local moveDown = cc.EaseOut:create(cc.MoveTo:create(during*3, cc.p(node:getPositionX(), posY)), 0.25);

    -- 还原
    local compressDown2 = cc.EaseOut:create(cc.ScaleTo:create(during*2, scaleX, scaleY-0.2), 2.5);
    local stretchUp2 = cc.EaseOut:create(cc.ScaleTo:create(during, scaleX, scaleY), 2.5);

    -- 动画
    node:runAction(cc.RepeatForever:create(cc.Sequence:create(moveUp, moveDown, compressDown2, stretchUp2)));
end

-- 更新动画
function UICommunicating:playProgressAnimation()
    local i = 1;
    local function loopPlay()
        if i <= 100 then
            local posX = self.loadingBar1BG:getContentSize().width / 100 * i + 30;
            self.pNode:setPositionX(-self.loadingBar1BG:getContentSize().width/2 + posX);

            if i > 3 then
                self.pNode:setVisible(true);
            end

            self.lastPercent = self.lastPercent or 3.3;
            if i >= self.lastPercent and math.floor(i) ~= 99 then
                self:grassEffect(i);
                self.lastPercent = self.lastPercent + 3.3;
            end

            if i > 93 then
                self.pNode:setVisible(false);
            end

            i = i + 1.42;
        else
            self.loadingBar1BG:removeAllChildren();
            self.lastPercent = 3.3;

            i = 1;
        end
    end

    local callFunc = cc.CallFunc:create(loopPlay);
    self.node:runAction(cc.RepeatForever:create(cc.Sequence:create(callFunc)));
end

-- 草地动画
function UICommunicating:grassEffect(percent)
    local curNum = math.floor(percent / 17.1);
    local curIndex = math.floor(percent / 3.3) % 5;
    curIndex = (curIndex == 0) and 5 or curIndex;

    local offset = 524 / 6 * curNum + grassOffset[curIndex] + 7;

    local grassImg = ccui.ImageView:create();
    local name = "g0" .. curIndex .. ".png";

    local iconPath = "images/ui/login/effect/" .. name;
    if not cc.SpriteFrameCache:getInstance():getSpriteFrame(iconPath) then
        cc.SpriteFrameCache:getInstance():addSpriteFrames("images/ui/login_effect.plist");
    end

    grassImg:loadTexture(iconPath, 1);
    grassImg:setAnchorPoint(0.5, 0.1);
    grassImg:setScale(0.05);

    local posX = self.loadingBar1BG:getContentSize().width/100 + offset;
    if posX > self.loadingBar1BG:getContentSize().width - 20 then
        grassImg:setVisible(false);
        return;
    end

    grassImg:setPosition(self.loadingBar1BG:getContentSize().width/100 + offset, offsetY);
    self.loadingBar1BG:addChild(grassImg);

    local time = math.random(1.5, 4) / 10;
    local scaleUp = cc.ScaleTo:create(time, 1.2);
    local scaleDown = cc.ScaleTo:create(time/5, 1);

    local function grassFlowerEffect(x, y, name)
        local flowerImg = ccui.ImageView:create();
        flowerImg:loadTexture("images/ui/login/effect/" .. name .. ".png", 1);
        flowerImg:setScale(0);
        flowerImg:setPosition(x, y);
        grassImg:addChild(flowerImg);

        local callFunc = cc.CallFunc:create(function()
            local flowerScaleUp = cc.ScaleTo:create(0.2, 1.2);
            local flowerScaleDown = cc.ScaleTo:create(0.05, 1);
            flowerImg:runAction(cc.Sequence:create(flowerScaleUp, flowerScaleDown));
        end);

        grassImg:runAction(cc.Sequence:create(scaleUp, scaleDown, callFunc));
    end

    if curIndex == 3 then
        grassFlowerEffect(20, 45, "f02");
    else
        local prob = math.random(0, 100);
        if prob > flowerProb then
            fX = math.random(0, 40);
            fY = math.random(25, 35);
            grassFlowerEffect(fX, fY, "f01");
        else
            grassImg:runAction(cc.Sequence:create(scaleUp, scaleDown));
        end
    end
end

-- 更新完所有动画
function UICommunicating:finishProgressAnimation()
    local i = self.lastPercent or 3.3;
    local function loopPlay()
        if i <= 100 then
            local posX = self.loadingBar1BG:getContentSize().width / 100 * i + 30;
            self.pNode:setPositionX(-self.loadingBar1BG:getContentSize().width/2 + posX);
            self.pNode:setVisible(true);

            self.lastPercent = self.lastPercent or 3.3;
            if i >= self.lastPercent and math.floor(i) ~= 99 then
                self:grassEffect(i);
                self.lastPercent = self.lastPercent + 3.3;
            end

            if i > 93 then
                self.pNode:setVisible(false);
            end

            i = i + 2;
        else
            self.pNode:setVisible(false);
            self.node:stopAllActions();

            self:finishEffect();
        end
    end

    self.pNode:stopAllActions();
    self:progressBarEffect(0.015, 10);

    local callFunc = cc.CallFunc:create(loopPlay);
    self.node:runAction(cc.RepeatForever:create(cc.Sequence:create(callFunc)));

    return 1.5;
end

-- 更新完毕的动画
function UICommunicating:finishEffect()
    -- 检查下有没有子节点，没有的话用通用的草地资源
    local childs = self.loadingBar1BG:getChildren();
    if not childs or #childs == 0 then
        local grassImg = ccui.ImageView:create();
        grassImg:loadTexture("images/ui/login/effect/progress.png");
        grassImg:setAnchorPoint(0.5, 0);
        grassImg:setPosition(self.loadingBar1BG:getContentSize().width/2, 3);
        self.loadingBar1BG:addChild(grassImg);
    end

    -- 更新完毕播放下进度条动画
    local scaleX = self.loadingBar1BG:getScaleX();
    local scaleY = self.loadingBar1BG:getScaleY();
    local scaleDown1 = cc.ScaleTo:create(0.1, scaleX, scaleY - 0.2);
    local scaleUp1   = cc.ScaleTo:create(0.1, scaleX, scaleY + 0.2);
    local scaleDown2 = cc.ScaleTo:create(0.1, scaleX, scaleY);

    self.loadingBar1BG:runAction(cc.Sequence:create(scaleDown1, scaleUp1, scaleDown2));
end
